package com.hospes.rmes.core;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.hospes.rmes.constants.ConstMain;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;

public class NetworkService {

	private HttpClient _httpClient;
	private FileManager _fileManager;

	public static final int STATUS_OK = 0;
	public static final int ERROR_USER_NOT_FOUND = 1;
	public static final int ERROR_ACTIVATION = 2;
	public static final int ERROR_USER_BANNED = 3;
	public static final int ERROR_PROVIDER_NOT_ACTIVE = 4;
	public static final int ERROR_PRODUCT_NOT_ACTIVE = 4;
	public static final int ERROR_WRONG_PARAMETERS = 100;
	public static final int ERROR_SERVER_FAULT = 200;
	public static final int ERROR_NOT_IMPLEMENTED = 500;
	public static final int ERROR_NETWORK = -1;

	public NetworkService() {
		_httpClient = createHttpClient();
		_fileManager = new FileManager(); 
	}

	public HttpClient getClient() {
		return _httpClient;
	}

	public void shutdownHttpClient() {
		if (_httpClient != null && _httpClient.getConnectionManager() != null) {
			_httpClient.getConnectionManager().shutdown();
		}
	}

	public Bitmap downloadImage(ImageDescriptor image) {
		String imageUrl = image.imageUrl;
		if (_fileManager.isImageCached(image)) {
			WeakReference<Bitmap> weakBitmap = _fileManager.restoreFromCacheWeak(image);
			if (weakBitmap != null && weakBitmap.get() != null) {
				return weakBitmap.get();
			} else
				return null;
		}
		final HttpGet getRequest = new HttpGet(imageUrl);
		try {
			HttpResponse response = _httpClient.execute(getRequest);
			_httpClient.getConnectionManager().closeExpiredConnections();
			
			final int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				Log.w(ConstMain.LOG_TAG, "Error " + statusCode + " while retrieving bitmap from " + imageUrl);
				return null;
			}
			Log.w(ConstMain.LOG_TAG, "Image downloaded from internet");
			final HttpEntity entity = response.getEntity();
			if (entity != null) {
				InputStream inputStream = null;
				try {
					inputStream = entity.getContent();
					BitmapFactory.Options options = new BitmapFactory.Options();
					options.inSampleSize = 1;
					WeakReference<Bitmap> bitmap;
					try {
						bitmap = new WeakReference<Bitmap>(BitmapFactory.decodeStream(new FlushedInputStream(inputStream), null, options));
						_fileManager.storeToCache(bitmap.get(), image);
					} catch (OutOfMemoryError e) {
						bitmap = null;
						Runtime.getRuntime().gc();
						return null;
					}
					return bitmap.get();
				} finally {
					if (inputStream != null) {
						inputStream.close();
						inputStream = null;
					}
					entity.consumeContent();
				}
			}
			
		} catch (IOException e) {
			getRequest.abort();
			Log.w(ConstMain.LOG_TAG, "IO error while retrieving bitmap from " + imageUrl);
		} catch (IllegalStateException e) {
			getRequest.abort();
			Log.w(ConstMain.LOG_TAG, "Incorrect URL: " + imageUrl);
		} catch (Exception e) {
			getRequest.abort();
			Log.w(ConstMain.LOG_TAG, "Error while retrieving bitmap from " + imageUrl);
		}
		return null;
	}

	private HttpClient createHttpClient() {
		HttpParams params = new BasicHttpParams();
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
		HttpProtocolParams.setUseExpectContinue(params, false);
		SchemeRegistry schReg = new SchemeRegistry();
		schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		ConnManagerParams.setMaxTotalConnections(params, 10);
		ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(params, schReg);
		return new DefaultHttpClient(connectionManager, params);
	}
}
